package com.arron.juc;

import java.util.concurrent.*;

/**
 * @Classname BlockingQueueDemo
 * @Description TODO
 * @Date 2020/8/21 16:18
 * @Created by 刘
 */
//阻塞队列
public class BlockingQueueDemo {


    /**
     * 好处是我们不需要关心什么时候需要阻塞线程，什么时候需要唤醒线程，因为这一切BlockingQueue都给你一手包办了
     */
    public static void main(String[] args) throws InterruptedException {

//        arryBlockingQueueApi();

        //只能存一个，如果没有人来取，就一直等待，只有有人来取了，才能进行put
        SynchronousQueue<String> strings = new SynchronousQueue<>();

        new Thread(()->{

            try {
                System.out.println(Thread.currentThread().getName()+"\t put a");
                strings.put("a");
                System.out.println(Thread.currentThread().getName()+"\t put b");
                strings.put("b");
                System.out.println(Thread.currentThread().getName()+"\t put c");
                strings.put("c");

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        },"AAA").start();

        new Thread(()->{
            try {

                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"\t take :"+strings.take());

                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"\t take :"+strings.take());

                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"\t take :"+strings.take());
            } catch (Exception e) {
                e.printStackTrace();
            }

        },"BBB").start();

    }

    /**
     * ArrayBlockingQueue
     * @throws InterruptedException
     */
    private static void arryBlockingQueueApi() throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
        BlockingQueue<String> blockingQueue2 = new LinkedBlockingQueue<>(3);
        //直接报异常
//        blockingQueue.add("a");
//        blockingQueue.add("a");
//        blockingQueue.add("a");
//
//        blockingQueue.add("a");
//
//        blockingQueue.remove();

        //线程阻塞，等待有空间了在添加
//        blockingQueue.put("a");
//        blockingQueue.put("a");
//        blockingQueue.put("a");
////        blockingQueue.put("a");
//
//        System.out.println(blockingQueue.take());
        //直接返回true或者false
//        System.out.println(blockingQueue.offer("a"));
//        System.out.println(blockingQueue.offer("a"));
//        System.out.println(blockingQueue.offer("a"));
//        System.out.println(blockingQueue.offer("a"));
//        System.out.println(blockingQueue.offer("a"));
//        System.out.println(blockingQueue.poll());

        //有时间的等待
        //超时控制
        System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));
        System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));
        System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));
        System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));

        System.out.println(blockingQueue.poll(2L, TimeUnit.SECONDS));
        System.out.println(blockingQueue.poll(2L, TimeUnit.SECONDS));
        System.out.println(blockingQueue.poll(2L, TimeUnit.SECONDS));
        System.out.println(blockingQueue.poll(2L, TimeUnit.SECONDS));
    }

}
